/**
 * This file is part of 1genia trampoline
 * Copyright (C) 2007 1genia (contact@1genia.com)
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; version 3 of the License. 
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; see the file COPYING.TXT.  If not,
 * write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA 02110-1301, USA. 
 **/
package com.genia.toolbox.basics.manager;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.List;

import javax.xml.validation.Schema;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.genia.toolbox.basics.exception.technical.TechnicalFileNotFoundException;
import com.genia.toolbox.basics.exception.technical.TechnicalIOException;
import com.genia.toolbox.basics.exception.technical.XmlException;

/**
 * Generic class for operation on xml files.
 */
public interface XmlManager
{

  /**
   * the method clone the intput document into a new document.
   * 
   * @param document
   *          the document cloned.
   * @return a new document with the root and the nodes of the document.
   * @throws XmlException
   *           technical problem during the transformation of the document.
   */
  public Document clone(Document document)
      throws XmlException;



  /**
   * returns the {@link List} of all sub-{@link Element} of a {@link Element}.
   * 
   * @param element
   *          the {@link Element} to explore
   * @return the {@link List} of all sub-{@link Element} of a {@link Element}
   */
  public List<Element> getAllSubElements(Element element);



  /**
   * returns the {@link List} of all sub-{@link Node} of a {@link Node}.
   * 
   * @param node
   *          the {@link Node} to explore
   * @return the {@link List} of all sub-{@link Node} of a {@link Node}
   */
  public List<Node> getAllSubNodes(Node node);



  /**
   * returns the value of an attribute of the {@link Element}. This method
   * return <code>null</code> if the attribute does not exist.
   * 
   * @param element
   *          the element to query
   * @param attributeName
   *          the name of the attribute to query
   * @return the value of the attribute of name attributeName, or
   *         <code>null</code> if no such attribute is defined
   */
  public String getAttribute(Element element, String attributeName);



  /**
   * returns the {@link List} of {@link Element} in a {@link NodeList}.
   * 
   * @param nodeList
   *          the {@link NodeList} to convert
   * @return the {@link List} of {@link Element} contained in the parameter
   *         {@link NodeList}
   */
  public List<Element> getElements(NodeList nodeList);



  /**
   * returns the {@link List} of {@link Element} in a {@link NodeList}.
   * 
   * @param tagName
   *          the name of the tag of the elements to get, <code>null</code> if
   *          all elements must be retrieved
   * @param nodeList
   *          the {@link NodeList} to convert
   * @return the {@link List} of {@link Element} contained in the parameter
   *         {@link NodeList}
   */
  public List<Element> getElements(String tagName, NodeList nodeList);



  /**
   * retrieve a {@link Schema} from {@link File}s.
   * 
   * @param files
   *          the {@link File}s containing the schema.
   * @return a {@link Schema}
   * @throws XmlException
   *           if an error occured
   */
  public Schema getSchema(File... files)
      throws XmlException;



  /**
   * retrieve a {@link Schema} from {@link InputStream}s.
   * 
   * @param inputStreams
   *          the {@link InputStream}s containing the schema.
   * @return a {@link Schema}
   * @throws XmlException
   *           if an error occured
   */
  public Schema getSchema(InputStream... inputStreams)
      throws XmlException;



  /**
   * the method create a new document. the version is "1.0".
   * 
   * @return a new document.
   * @throws XmlException
   *           problem during the transformation of the document.
   */
  public Document newDocument()
      throws XmlException;



  /**
   * the method parse a file.
   * 
   * @param file
   *          input parameter.
   * @return the document from parsing.
   * @throws XmlException
   *           technical problem during the parsing of the xml stream.
   * @throws TechnicalIOException
   *           when an I/O error occurred
   */
  public Document parse(File file)
      throws XmlException, TechnicalIOException;



  /**
   * the method parse an inputStream.
   * 
   * @param inputStream
   *          input parameter.
   * @return the document from parsing.
   * @throws XmlException
   *           technical problem during the parsing of the xml stream.
   * @throws TechnicalIOException
   *           when an I/O error occure
   */
  public Document parse(InputStream inputStream)
      throws XmlException, TechnicalIOException;



  /**
   * the method transform the document into a file.
   * 
   * @param document
   *          the document input to transform.
   * @param file
   *          the result output is of type File.
   * @throws TechnicalFileNotFoundException
   *           exception thrown in case of wrong url's file or missing file.
   * @throws XmlException
   *           technical problem during the transformation of the xml document.
   */
  public void print(Document document, File file)
      throws TechnicalFileNotFoundException, XmlException;



  /**
   * the method transform the document into an outputStream.
   * 
   * @param document
   *          the document input to transform.
   * @param outputStream
   *          the result output is an outputStream.
   * @throws XmlException
   *           technical problem during the transformation of the xml document.
   */
  public void print(Document document, OutputStream outputStream)
      throws XmlException;



  /**
   * strip all node that are only whitespace text.
   * 
   * @param node
   *          the root node to explore
   */
  public void stripWhiteSpaceNodes(Node node);



  /**
   * the method transform an xml file with the xsl.
   * 
   * @param xslDocument
   *          the input xsl file is of type "Document".
   * @param xmlDocument
   *          the input xml file is of type "Document".
   * @return a document transformed with the xsl document.
   * @throws XmlException
   *           technical problem during the transformation of the xml document.
   */
  public Document transform(Document xslDocument, Document xmlDocument)
      throws XmlException;



  /**
   * the method transform an xml file with the xsl.
   * 
   * @param xslFile
   *          the input xsl file.
   * @param xmlFile
   *          the input xml file.
   * @return a document transformed with an xsl file.
   * @throws XmlException
   *           technical problem during the transformation of the xml document.
   * @throws TechnicalIOException
   *           when an I/O error occurred
   */
  public Document transform(File xslFile, File xmlFile)
      throws XmlException, TechnicalIOException;



  /**
   * the method transform an xml InputStream with an xsl InputStream.
   * 
   * @param xslStream
   *          the input xsl file is of type "InputStream".
   * @param xmlDocument
   *          the input xml file is of type "InputStream".
   * @return a document transformed with an xsl stream.
   * @throws XmlException
   *           technical problem during the transformation of the xml document.
   */
  public Document transform(InputStream xslStream, Document xmlDocument)
      throws XmlException;



  /**
   * the method transform an xml InputStream with the xsl InputStream.
   * 
   * @param xslStream
   *          the input xsl file is of type "InputStream".
   * @param xmlStream
   *          the input xml file is of type "InputStream".
   * @return a document transformed with an xsl file.
   * @throws XmlException
   *           technical problem during the transformation of the xml document.
   * @throws TechnicalIOException
   *           when an I/O error occurred
   */
  public Document transform(InputStream xslStream, InputStream xmlStream)
      throws XmlException, TechnicalIOException;



  /**
   * the method transform an xml document given by its {@link URL} with an xsl
   * document given by its {@link URL} and returns a {@link Document}
   * representing the result.
   * 
   * @param xslUrl
   *          the {@link URL} representing the XSL file
   * @param xmlUrl
   *          the {@link URL} representing the XML file
   * @return the {@link Document} representing the result of the transformation
   * @throws XmlException
   *           technical problem during the transformation of the document.
   */
  public Document transform(final URL xslUrl, final URL xmlUrl)
      throws XmlException;
}
